package org.swidgets.base.sinputbox;



import org.swidgets.base.Validate;
import org.swidgets.base.stooltip.SToolTip;
import org.swidgets.base.stooltip.SToolTipTypeRepository;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.ChangeListener;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FocusListener;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.KeyboardListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.MouseListener;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.client.ui.TextBoxBase.TextAlignConstant;

public class SInputBox extends Composite implements FocusListener,  MouseListener, Validate{
	
	
	private HorizontalPanel hp = new HorizontalPanel();
	private TextBox textBox= new TextBox();  
	private SToolTip toolTip; 
	private Image icon = new Image("style/img/icons/error.gif"); 
	private PopupPanel popupPanel;
	private String label  = new String();
	private Label sLabel = new Label();
	private boolean requied = false;
	private boolean error = false;
	private boolean validated = true; 
	private AsyncDataValidator asyncDataValidator;
	
	private static final boolean isDesignTime() {
		return false;
	}
	
	private void initSimpleBox(){
		hp.add(sLabel);
		hp.add(textBox);
	
		textBox.addFocusListener(this);
		textBox.setStyleName("InPutBoxEnabled");
		sLabel.setText(label);
		sLabel.setStyleName("defaultLabel");
		icon.addMouseListener(this);
		getImgContainer().add(icon);
		icon.setVisible(false);
		hp.setCellWidth(icon, "16px");
		if (isDesignTime()) {
			this.setText("InputBox");		
		}
	}
	
	public SInputBox() {
		initWidget(hp);
		initSimpleBox();
	
	}
	
	public SInputBox( AsyncDataValidator asyncDataValidator) {
		this.asyncDataValidator = asyncDataValidator;
		initWidget(hp);
		initSimpleBox();
	}
	
	public SInputBox(String label) {
		initWidget(hp);
		this.label = label;
		initSimpleBox();
	
	}
	
	public SInputBox(String label, AsyncDataValidator asyncDataValidator ) {
		this.asyncDataValidator = asyncDataValidator;
		initWidget(hp);
		this.label = label;
		initSimpleBox();
	
	}
	
	
	public void validate(final AsyncCallback callback) {
		checkIcon();
		//icon.setVisible(false);
		//textBox.setStyleName("InPutBoxEnabled");
		if ( requied && getText().length() == 0 ) {
			errorOn("Campo obbligatorio");
			if(callback!=null)
				callback.onFailure(new Exception("Campo obbligatorio"));
		} else {
			if (asyncDataValidator != null ){
				asyncDataValidator.validate(getText(), new  AsyncCallback(){
						public void onFailure(Throwable caught) {
							errorOn(caught.getMessage());
							if(callback!=null)
								callback.onFailure(caught);
						}
						public void onSuccess(Object result) {
							if(validated){
								errorOff();
								if(callback!=null)
									callback.onSuccess(result);								
							}
							else{
								if(callback!=null)
									callback.onFailure(new Exception("Errore di validazione"));
							}
						}
					});
			} else {
				if(callback!=null){
					if(validated){
						errorOff();
						if(callback!=null)
							callback.onSuccess(new String("ok"));								
					}
					else{
						if(callback!=null)
							callback.onFailure(new Exception("Errore di validazione"));
					}
				}
			} 
			
		}
		
	}
	

//	public void validate() {
//	
//		if ( requied && getText().length() == 0 ) {
//			errorOn("Campo obbligatorio");
//		} else {
//			if ( asyncDataValidator != null ){
//				validated=-1;
//				asyncDataValidator.validate(getText(), new  AsyncCallback(){
//						public void onFailure(Throwable caught) {
//							errorOn(caught.getMessage());
//							
//						}
//						public void onSuccess(Object result) {
//							errorOff();
//							
//						}
//					});
//			} else {
//				errorOff();
//			} 
//			
//		}
//		
//	}
	public void errorOn(String errorMessage) {
		
		validated = false;
		
		if(toolTip==null)
			toolTip=  new SToolTip();
		toolTip.setMessage(SToolTipTypeRepository.error, errorMessage);
		error = true;
		textBox.setStyleName("InPutBoxOnError");
		
		/*if(icon==null){
			icon = new Image("style/img/icons/error.gif");
			icon.addMouseListener(this);
			getImgContainer().add(icon);
		}*/
		
		checkIcon();
		icon.setVisible(true);
		
	}
	
	protected Panel getImgContainer(){
		return hp;
	}
	
	private void checkIcon(){
		if(icon==null){
			icon = new Image("style/img/icons/error.gif");
			icon.addMouseListener(this);
			getImgContainer().add(icon);
		}	
	}
	
	public void errorOff() {
		
		validated = true;
		
		error = false;
		textBox.setStyleName("InPutBoxEnabled");
		checkIcon();
		icon.setVisible(false);
	}
	
	public void setLabel(String label){
		this.label = label;
		sLabel.setText(label);
	}

	public void onFocus(Widget sender) {
		if (!error){
			textBox.setStyleName("InPutBoxOnFocus");
		}
	}

	public void onLostFocus(Widget sender) {
		textBox.setStyleName("InPutBoxEnabled");
		checkIcon();
		icon.setVisible(false);
		
		this.validate(null);
	}

	public void onMouseDown(Widget sender, int x, int y) {
		// TODO Auto-generated method stub
	}

	public void onMouseEnter(Widget sender) {
		toolTip.setVisible(true);
		if(popupPanel==null)
			popupPanel = new PopupPanel();
		popupPanel.clear();
		popupPanel.add(toolTip);
		popupPanel.setPopupPosition(icon.getAbsoluteLeft()+10, icon.getAbsoluteTop()+15);
		popupPanel.show();
	}

	public void onMouseLeave(Widget sender) {
		toolTip.setVisible(false);
		
	}

	public void onMouseMove(Widget sender, int x, int y) {
		// TODO Auto-generated method stub
	}

	public void onMouseUp(Widget sender, int x, int y) {
		// TODO Auto-generated method stub
	}

	public void addChangeListener(ChangeListener listener) {
		textBox.addChangeListener(listener);
	}

	public void addClickListener(ClickListener listener) {
		textBox.addClickListener(listener);
	}

	public void addFocusListener(FocusListener listener) {
		textBox.addFocusListener(listener);
	}

	public void addKeyboardListener(KeyboardListener listener) {
		textBox.addKeyboardListener(listener);
	}

	public void addStyleDependentName(String styleSuffix) {
		textBox.addStyleDependentName(styleSuffix);
	}

	public void addStyleName(String style) {
		textBox.addStyleName(style);
	}

	public void cancelKey() {
		textBox.cancelKey();
	}

	public boolean equals(Object obj) {
		return textBox.equals(obj);
	}

	public int getMaxLength() {
		return textBox.getMaxLength();
	}

	public String getSelectedText() {
		return textBox.getSelectedText();
	}

	public int getSelectionLength() {
		return textBox.getSelectionLength();
	}

	public String getText() {
		return textBox.getText();
	}

	public String getTitle() {
		return textBox.getTitle();
	}

	public boolean isReadOnly() {
		return textBox.isReadOnly();
	}

	public void removeChangeListener(ChangeListener listener) {
		textBox.removeChangeListener(listener);
	}

	public void removeClickListener(ClickListener listener) {
		textBox.removeClickListener(listener);
	}

	public void removeFocusListener(FocusListener listener) {
		textBox.removeFocusListener(listener);
	}

	public void removeKeyboardListener(KeyboardListener listener) {
		textBox.removeKeyboardListener(listener);
	}

	public void setCursorPos(int pos) {
		textBox.setCursorPos(pos);
	}

	public void setEnabled(boolean enabled) {
		textBox.setEnabled(enabled);
		if ( ! enabled ){
			textBox.setStyleName("InPutBoxDisabled");
			return;
		} else {
			textBox.setStyleName("InPutBoxEnabled");
		}
			
		
	}

	public void setFocus(boolean focused) {
		textBox.setFocus(focused);
	}

	public void setMaxLength(int length) {
		textBox.setMaxLength(length);
	}

	public void setReadOnly(boolean readOnly) {
		textBox.setReadOnly(readOnly);
	}

	public void setTabIndex(int index) {
		textBox.setTabIndex(index);
	}

	public void setText(String text) {
		textBox.setText(text);
		this.onLostFocus(this);
	}

	public void setTextAlignment(TextAlignConstant align) {
		textBox.setTextAlignment(align);
	}

	public void setTitle(String title) {
		textBox.setTitle(title);
	}

	public void g(String width) {
		textBox.setWidth(width);
	}

	public boolean isEnabled() {
		return textBox.isEnabled();
	}

	public boolean isRequied() {
		return requied;
	}

	public void setRequied(boolean requied) {
		this.validated = false;
		this.requied = requied;
		sLabel.setText(requied?"*" + label : label);
	}

	public void setAsyncDataValidator(AsyncDataValidator asyncDataValidator) {
		this.asyncDataValidator = asyncDataValidator;
	}

	public boolean isValidated() {		
		return  validated;
	}
		
	//delegated methods for textBox
	
	public void selectAll() {
		textBox.selectAll();
	}

	public void setAccessKey(char key) {
		textBox.setAccessKey(key);
	}

	public void setSelectionRange(int pos, int length) {
		textBox.setSelectionRange(pos, length);
	}

	public int getCursorPos() {
		return textBox.getCursorPos();
	}

	public int getAbsoluteLeft() {
		return textBox.getAbsoluteLeft();
	}

	public int getAbsoluteTop() {
		return textBox.getAbsoluteTop();
	}

	public int getOffsetHeight() {
		return textBox.getOffsetHeight();
	}

	public int getOffsetWidth() {
		return textBox.getOffsetWidth();
	}	
	
	
}
